package com.sdx.console.crm.web;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sdx.common.utils.SpringUtils;
import com.sdx.console.crm.entity.CrmMessage;
import com.sdx.console.crm.service.CrmChatService;
import com.sdx.console.crm.service.CrmSessionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Map;

@ServerEndpoint("/websocket/{userId}")
@Component
public class WebSocketServer {
    static Logger log = LoggerFactory.getLogger(WebSocketServer.class);

    /**
     * 用来记录userId和该WebSocket 进行绑定
     */
    private static Map<String, WebSocketServer> webSocketMap = new Hashtable<>();

    /***
     * 与某个客户端的连接会话，需要通过它来给客户端发送数据
     */
    private Session session;

    private String userId;

    /**
     * 连接建立成功调用的方法     
     */
    @OnOpen
    public void onOpen(Session session,@PathParam("userId") String userId) {
        this.session = session;
        this.userId = userId;
        webSocketMap.put(userId, this);
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        //从set中删除
        close(this);
    }


    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message,Session session,@PathParam("userId")String userId) {
        //从客户端传过来的数据是json数据
        JSONObject json = JSON.parseObject(message);
        try {
            json.put("userId",userId);
            SpringUtils.getBean(CrmChatService.class).sendMessage(json);
        }catch(Exception e) {
            log.error("发送给客户消息",e);
        }
    }

    /**
     * 发生错误时调用         
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("错误调用",error);
    }

    /**
     * 根据用户ID得到 相应的 session
     * @param id
     * @return
     */
    public static Session getSessionById(String id){
        return  webSocketMap.get(id).session;
    }

	/**
	 * 把crmMessage消息发送到userId代表的websocket
	 * @param userId
	 * @param crmMessage
	 */
	public static void sendMessage(Integer userId, CrmMessage crmMessage) {
		//把crmMessage消息发送到userId代表的websocket
        WebSocketServer webSocketServer = webSocketMap.get(userId.toString());
        CrmChatService crmChatService = SpringUtils.getBean(CrmChatService.class);
        CrmSessionService crmSessionService = SpringUtils.getBean(CrmSessionService.class);
        try {
            if(webSocketServer!=null && webSocketServer.session!=null){
                crmSessionService.sendUpdate(crmMessage.getSessionId(),1);
                webSocketServer.session.getAsyncRemote().sendText(crmChatService.sendParam(crmMessage));
            }
        } catch (Exception e) {
            log.error("发送给客服消息",e);
        }
    }

	/**
	 * 清除userId代表客服的相关websocket和session
	 * @param userId
	 */
	public static void removeWebSocket(Integer userId) {
		//清除userId代表客服的相关websocket和session
        close(webSocketMap.get(userId));
    }

    /**
     * 关闭websocket 、 session
     * @param webSocketServer
     */
    public static void close(WebSocketServer webSocketServer){
        try {
            if(webSocketServer!=null){
                webSocketMap.remove(webSocketServer.userId);
                webSocketServer.session.close();
                SpringUtils.getBean(CrmChatService.class).closeSession(webSocketServer.userId);
            }
        } catch (IOException e) {
            log.error("关闭websocket",e);
        }
    }
}
